{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "# 第二课：图游走类算法习题\n",
    "\n",
    "本节实践主要涉及到DeepWalk和Node2Vec的关键代码，目的是让同学们能够进一步理解、使用以及根据自身需求修改这些模块。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Looking in indexes: https://mirror.baidu.com/pypi/simple/\n",
      "Collecting pgl\n",
      "\u001b[?25l  Downloading https://mirror.baidu.com/pypi/packages/e2/84/6aac242f80a794f1169386d73bdc03f2e3467e4fa85b1286979ddf51b1a0/pgl-1.2.1-cp37-cp37m-manylinux1_x86_64.whl (7.9MB)\n",
      "\u001b[K     |████████████████████████████████| 7.9MB 14.0MB/s eta 0:00:01\n",
      "\u001b[?25hRequirement already satisfied: numpy>=1.16.4 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pgl) (1.16.4)\n",
      "Requirement already satisfied: cython>=0.25.2 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pgl) (0.29)\n",
      "Collecting redis-py-cluster (from pgl)\n",
      "\u001b[?25l  Downloading https://mirror.baidu.com/pypi/packages/2b/c5/3236720746fa357e214f2b9fe7e517642329f13094fc7eb339abd93d004f/redis_py_cluster-2.1.0-py2.py3-none-any.whl (41kB)\n",
      "\u001b[K     |████████████████████████████████| 51kB 20.5MB/s eta 0:00:01\n",
      "\u001b[?25hRequirement already satisfied: visualdl>=2.0.0b; python_version >= \"3\" in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pgl) (2.0.3)\n",
      "Collecting redis<4.0.0,>=3.0.0 (from redis-py-cluster->pgl)\n",
      "\u001b[?25l  Downloading https://mirror.baidu.com/pypi/packages/a7/7c/24fb0511df653cf1a5d938d8f5d19802a88cef255706fdda242ff97e91b7/redis-3.5.3-py2.py3-none-any.whl (72kB)\n",
      "\u001b[K     |████████████████████████████████| 81kB 27.1MB/s eta 0:00:01\n",
      "\u001b[?25hRequirement already satisfied: Flask-Babel>=1.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0b; python_version >= \"3\"->pgl) (1.0.0)\n",
      "Requirement already satisfied: six>=1.14.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0b; python_version >= \"3\"->pgl) (1.15.0)\n",
      "Requirement already satisfied: flask>=1.1.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0b; python_version >= \"3\"->pgl) (1.1.1)\n",
      "Requirement already satisfied: Pillow>=7.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0b; python_version >= \"3\"->pgl) (7.1.2)\n",
      "Requirement already satisfied: protobuf>=3.11.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0b; python_version >= \"3\"->pgl) (3.12.2)\n",
      "Requirement already satisfied: requests in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0b; python_version >= \"3\"->pgl) (2.22.0)\n",
      "Requirement already satisfied: flake8>=3.7.9 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0b; python_version >= \"3\"->pgl) (3.8.2)\n",
      "Requirement already satisfied: pre-commit in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from visualdl>=2.0.0b; python_version >= \"3\"->pgl) (1.21.0)\n",
      "Requirement already satisfied: pytz in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from Flask-Babel>=1.0.0->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (2019.3)\n",
      "Requirement already satisfied: Jinja2>=2.5 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from Flask-Babel>=1.0.0->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (2.10.3)\n",
      "Requirement already satisfied: Babel>=2.3 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from Flask-Babel>=1.0.0->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (2.8.0)\n",
      "Requirement already satisfied: itsdangerous>=0.24 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flask>=1.1.1->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (1.1.0)\n",
      "Requirement already satisfied: Werkzeug>=0.15 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flask>=1.1.1->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (0.16.0)\n",
      "Requirement already satisfied: click>=5.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flask>=1.1.1->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (7.0)\n",
      "Requirement already satisfied: setuptools in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from protobuf>=3.11.0->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (41.4.0)\n",
      "Requirement already satisfied: idna<2.9,>=2.5 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (2.8)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (2019.9.11)\n",
      "Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (3.0.4)\n",
      "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from requests->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (1.25.6)\n",
      "Requirement already satisfied: mccabe<0.7.0,>=0.6.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8>=3.7.9->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (0.6.1)\n",
      "Requirement already satisfied: importlib-metadata; python_version < \"3.8\" in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8>=3.7.9->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (0.23)\n",
      "Requirement already satisfied: pycodestyle<2.7.0,>=2.6.0a1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8>=3.7.9->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (2.6.0)\n",
      "Requirement already satisfied: pyflakes<2.3.0,>=2.2.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from flake8>=3.7.9->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (2.2.0)\n",
      "Requirement already satisfied: identify>=1.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (1.4.10)\n",
      "Requirement already satisfied: cfgv>=2.0.0 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (2.0.1)\n",
      "Requirement already satisfied: virtualenv>=15.2 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (16.7.9)\n",
      "Requirement already satisfied: aspy.yaml in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (1.3.0)\n",
      "Requirement already satisfied: nodeenv>=0.11.1 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (1.3.4)\n",
      "Requirement already satisfied: toml in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (0.10.0)\n",
      "Requirement already satisfied: pyyaml in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pre-commit->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (5.1.2)\n",
      "Requirement already satisfied: MarkupSafe>=0.23 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from Jinja2>=2.5->Flask-Babel>=1.0.0->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (1.1.1)\n",
      "Requirement already satisfied: zipp>=0.5 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from importlib-metadata; python_version < \"3.8\"->flake8>=3.7.9->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (0.6.0)\n",
      "Requirement already satisfied: more-itertools in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from zipp>=0.5->importlib-metadata; python_version < \"3.8\"->flake8>=3.7.9->visualdl>=2.0.0b; python_version >= \"3\"->pgl) (7.2.0)\n",
      "Installing collected packages: redis, redis-py-cluster, pgl\n",
      "Successfully installed pgl-1.2.1 redis-3.5.3 redis-py-cluster-2.1.0\n"
     ]
    }
   ],
   "source": [
    "# 安装依赖\n",
    "# !pip install paddlepaddle==1.8.5\n",
    "!pip install pgl"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## 1. DeepWalk采样算法\n",
    "\n",
    "Graph类的实现可参考 PGL/pgl/graph.py，DeepWalk的代码详见 ./deepwalk.py\n",
    "\n",
    "\tNOTE：对于给定的节点，DeepWalk会等概率的选取下一个相邻节点加入路径，直至达到最大路径长度，或者没有下一个节点可选。\n",
    "\n",
    "<img src=\"https://ai-studio-static-online.cdn.bcebos.com/159e470f09bb4e12bae080a4733d46d0861a08e812e643d5b8b7f080b16f2e38\" width=\"85%\" height=\"85%\" />\n",
    "\n",
    "请实现Graph类的random_walk函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing userdef_graph.py\n"
     ]
    }
   ],
   "source": [
    "%%writefile userdef_graph.py\n",
    "from pgl.graph import Graph\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "class UserDefGraph(Graph):\n",
    "    def random_walk(self, nodes, walk_len):\n",
    "        \"\"\"\n",
    "        输入：nodes - 当前节点id list (batch_size,)\n",
    "             walk_len - 最大路径长度 int\n",
    "        输出：以当前节点为起点得到的路径 list (batch_size, walk_len)\n",
    "\n",
    "        用到的函数\n",
    "        1. self.successor(nodes)\n",
    "           描述：获取当前节点的下一个相邻节点id列表\n",
    "           输入：nodes - list (batch_size,)\n",
    "           输出：succ_nodes - list of list ((num_successors_i,) for i in range(batch_size))\n",
    "        2. self.outdegree(nodes)\n",
    "           描述：获取当前节点的出度\n",
    "           输入：nodes - list (batch_size,)\n",
    "           输出：out_degrees - list (batch_size,)\n",
    "        \"\"\"\n",
    "        walks = [[node] for node in nodes]\n",
    "\n",
    "        walks_ids = np.arange(0, len(nodes))\n",
    "        cur_nodes = np.array(nodes)\n",
    "        for l in range(walk_len):\n",
    "            \"\"\"选取有下一个节点的路径继续采样，否则结束\"\"\"\n",
    "            outdegree = self.outdegree(cur_nodes)\n",
    "            walk_mask = (outdegree != 0)\n",
    "            if not np.any(walk_mask):\n",
    "               break\n",
    "            cur_nodes = cur_nodes[walk_mask]\n",
    "            walks_ids = walks_ids[walk_mask]\n",
    "            outdegree = outdegree[walk_mask]\n",
    "\n",
    "            ######################################\n",
    "            # 请在此补充代码采样出下一个节点\n",
    "            succ_nodes = self.successor(cur_nodes)\n",
    "\n",
    "            sample_index = np.floor(np.random.rand(outdegree.shape[0]) * outdegree).astype(\"int64\")\n",
    "            next_nodes = []\n",
    "            for s, ind, walk_id in zip(succ_nodes, sample_index, walks_ids):\n",
    "                walks[walk_id].append(s[ind])\n",
    "                next_nodes.append(s[ind])\n",
    "\n",
    "            ######################################\n",
    "            cur_nodes = np.array(next_nodes)\n",
    "        return walks"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/sklearn/externals/joblib/externals/cloudpickle/cloudpickle.py:47: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses\n",
      "  import imp\n",
      "[INFO] 2020-11-25 13:01:52,146 [my_deepwalk.py:  274]:\tNamespace(batch_size=512, epoch=5, hidden_size=128, neg_num=20, processes=2, save_path='./tmp/deepwalk', use_my_random_walk=True, walk_len=5, win_size=5)\n",
      "[INFO] 2020-11-25 13:01:53,120 [my_deepwalk.py:  192]:\tStart random walk on disk...\n",
      "[INFO] 2020-11-25 13:01:53,950 [my_deepwalk.py:  203]:\tRandom walk on disk Done.\n",
      "2020-11-25 13:01:53,952-WARNING: paddle.fluid.layers.py_reader() may be deprecated in the near future. Please use paddle.fluid.io.DataLoader.from_generator() instead.\n",
      "[INFO] 2020-11-25 13:01:54,763 [my_deepwalk.py:  250]:\tStep 1 DeepWalk Loss: 0.723897  0.568443 s/step.\n",
      "[INFO] 2020-11-25 13:01:57,646 [my_deepwalk.py:  250]:\tStep 10 DeepWalk Loss: 0.712914  0.312942 s/step.\n",
      "[INFO] 2020-11-25 13:02:00,731 [my_deepwalk.py:  250]:\tStep 20 DeepWalk Loss: 0.685883  0.322055 s/step.\n",
      "[INFO] 2020-11-25 13:02:03,868 [my_deepwalk.py:  250]:\tStep 30 DeepWalk Loss: 0.657211  0.315109 s/step.\n",
      "[INFO] 2020-11-25 13:02:06,902 [my_deepwalk.py:  250]:\tStep 40 DeepWalk Loss: 0.607896  0.300344 s/step.\n",
      "[INFO] 2020-11-25 13:02:09,956 [my_deepwalk.py:  250]:\tStep 50 DeepWalk Loss: 0.581623  0.314348 s/step.\n",
      "[INFO] 2020-11-25 13:02:13,024 [my_deepwalk.py:  250]:\tStep 60 DeepWalk Loss: 0.557236  0.313549 s/step.\n",
      "[INFO] 2020-11-25 13:02:16,164 [my_deepwalk.py:  250]:\tStep 70 DeepWalk Loss: 0.527293  0.323529 s/step.\n",
      "[INFO] 2020-11-25 13:02:19,283 [my_deepwalk.py:  250]:\tStep 80 DeepWalk Loss: 0.486576  0.311172 s/step.\n",
      "[INFO] 2020-11-25 13:02:22,399 [my_deepwalk.py:  250]:\tStep 90 DeepWalk Loss: 0.461691  0.304235 s/step.\n",
      "[INFO] 2020-11-25 13:02:25,405 [my_deepwalk.py:  250]:\tStep 100 DeepWalk Loss: 0.432810  0.291704 s/step.\n",
      "[INFO] 2020-11-25 13:02:28,414 [my_deepwalk.py:  250]:\tStep 110 DeepWalk Loss: 0.413059  0.306615 s/step.\n",
      "[INFO] 2020-11-25 13:02:31,431 [my_deepwalk.py:  250]:\tStep 120 DeepWalk Loss: 0.393434  0.299223 s/step.\n",
      "[INFO] 2020-11-25 13:02:34,396 [my_deepwalk.py:  250]:\tStep 130 DeepWalk Loss: 0.386678  0.297187 s/step.\n",
      "[INFO] 2020-11-25 13:02:37,376 [my_deepwalk.py:  250]:\tStep 140 DeepWalk Loss: 0.374497  0.300225 s/step.\n",
      "[INFO] 2020-11-25 13:02:40,356 [my_deepwalk.py:  250]:\tStep 150 DeepWalk Loss: 0.360890  0.297040 s/step.\n",
      "[INFO] 2020-11-25 13:02:43,368 [my_deepwalk.py:  250]:\tStep 160 DeepWalk Loss: 0.361464  0.301396 s/step.\n",
      "[INFO] 2020-11-25 13:02:46,322 [my_deepwalk.py:  250]:\tStep 170 DeepWalk Loss: 0.355111  0.305382 s/step.\n",
      "[INFO] 2020-11-25 13:02:49,345 [my_deepwalk.py:  250]:\tStep 180 DeepWalk Loss: 0.347293  0.299917 s/step.\n",
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/sklearn/externals/joblib/externals/cloudpickle/cloudpickle.py:47: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses\n",
      "  import imp\n",
      "[INFO] 2020-11-25 13:02:52,498 [link_predict.py:  243]:\tNamespace(batch_size=None, ckpt_path='./tmp/deepwalk/paddle_model', dataset='ArXiv', epoch=100, hidden_size=128, use_cuda=False)\n",
      "2020-11-25 13:02:53,613-WARNING: paddle.fluid.layers.py_reader() may be deprecated in the near future. Please use paddle.fluid.io.DataLoader.from_generator() instead.\n",
      "2020-11-25 13:02:53,638-WARNING: paddle.fluid.layers.py_reader() may be deprecated in the near future. Please use paddle.fluid.io.DataLoader.from_generator() instead.\n",
      "[INFO] 2020-11-25 13:02:54,533 [link_predict.py:  199]:\tStep 1 Train Loss: 0.837671 Train AUC: 0.547416 \n",
      "[INFO] 2020-11-25 13:02:54,766 [link_predict.py:  223]:\t\t\tStep 1 Test Loss: 0.971486 Test AUC: 0.445466 \n",
      "[INFO] 2020-11-25 13:02:57,696 [link_predict.py:  199]:\tStep 10 Train Loss: 0.803860 Train AUC: 0.481341 \n",
      "[INFO] 2020-11-25 13:02:57,848 [link_predict.py:  223]:\t\t\tStep 10 Test Loss: 0.776949 Test AUC: 0.492330 \n",
      "[INFO] 2020-11-25 13:03:01,233 [link_predict.py:  199]:\tStep 20 Train Loss: 0.731187 Train AUC: 0.506023 \n",
      "[INFO] 2020-11-25 13:03:01,386 [link_predict.py:  223]:\t\t\tStep 20 Test Loss: 0.720863 Test AUC: 0.515769 \n",
      "[INFO] 2020-11-25 13:03:04,720 [link_predict.py:  199]:\tStep 30 Train Loss: 0.695324 Train AUC: 0.542586 \n",
      "[INFO] 2020-11-25 13:03:04,870 [link_predict.py:  223]:\t\t\tStep 30 Test Loss: 0.691954 Test AUC: 0.551983 \n",
      "[INFO] 2020-11-25 13:03:08,097 [link_predict.py:  199]:\tStep 40 Train Loss: 0.679217 Train AUC: 0.608623 \n",
      "[INFO] 2020-11-25 13:03:08,239 [link_predict.py:  223]:\t\t\tStep 40 Test Loss: 0.678707 Test AUC: 0.616755 \n",
      "[INFO] 2020-11-25 13:03:11,348 [link_predict.py:  199]:\tStep 50 Train Loss: 0.672300 Train AUC: 0.684436 \n",
      "[INFO] 2020-11-25 13:03:11,491 [link_predict.py:  223]:\t\t\tStep 50 Test Loss: 0.672842 Test AUC: 0.684239 \n",
      "[INFO] 2020-11-25 13:03:14,604 [link_predict.py:  199]:\tStep 60 Train Loss: 0.668637 Train AUC: 0.726166 \n",
      "[INFO] 2020-11-25 13:03:14,753 [link_predict.py:  223]:\t\t\tStep 60 Test Loss: 0.669521 Test AUC: 0.719124 \n",
      "[INFO] 2020-11-25 13:03:17,885 [link_predict.py:  199]:\tStep 70 Train Loss: 0.666206 Train AUC: 0.746659 \n",
      "[INFO] 2020-11-25 13:03:18,031 [link_predict.py:  223]:\t\t\tStep 70 Test Loss: 0.667123 Test AUC: 0.737879 \n",
      "[INFO] 2020-11-25 13:03:21,178 [link_predict.py:  199]:\tStep 80 Train Loss: 0.664544 Train AUC: 0.757289 \n",
      "[INFO] 2020-11-25 13:03:21,320 [link_predict.py:  223]:\t\t\tStep 80 Test Loss: 0.665469 Test AUC: 0.749857 \n",
      "[INFO] 2020-11-25 13:03:24,430 [link_predict.py:  199]:\tStep 90 Train Loss: 0.663446 Train AUC: 0.759262 \n",
      "[INFO] 2020-11-25 13:03:24,575 [link_predict.py:  223]:\t\t\tStep 90 Test Loss: 0.664433 Test AUC: 0.752329 \n",
      "[INFO] 2020-11-25 13:03:27,700 [link_predict.py:  199]:\tStep 100 Train Loss: 0.662990 Train AUC: 0.762379 \n",
      "[INFO] 2020-11-25 13:03:27,845 [link_predict.py:  223]:\t\t\tStep 100 Test Loss: 0.664039 Test AUC: 0.754957 \n"
     ]
    }
   ],
   "source": [
    "!python my_deepwalk.py --use_my_random_walk --epoch 5 # 用自己实现的random walk训练DeepWalk模型，可在 ./tmp/deepwalk/walks/ 中查看构造的节点路径\r\n",
    "!python link_predict.py --ckpt_path ./tmp/deepwalk/paddle_model --epoch 100 #测试"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## 2. SkipGram模型训练\n",
    "\n",
    "\tNOTE：在得到节点路径后，node2vec会使用SkipGram模型学习节点表示，给定中心节点，预测局部路径中还有哪些节点。模型中用了negative sampling来降低计算量。\n",
    "\n",
    "<img src=\"https://ai-studio-static-online.cdn.bcebos.com/5ee18998f2c84598a01a43aad15270f154f837dc972747e3aa69d6c2eb7d5d10\" width=\"85%\" height=\"85%\" />\n",
    "\n",
    "请你实现一下loss的计算过程吧。可参考 PGL/examples/node2vec/node2vec.py 中的 node2vec_model 函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing userdef_model.py\n"
     ]
    }
   ],
   "source": [
    "%%writefile userdef_model.py\n",
    "import paddle.fluid.layers as l\n",
    "\n",
    "def userdef_loss(embed_src, weight_pos, weight_negs):\n",
    "    \"\"\"\n",
    "    输入：embed_src   - 中心节点向量 list (batch_size, 1, embed_size)\n",
    "         weight_pos  - 标签节点向量 list (batch_size, 1, embed_size)\n",
    "         weight_negs - 负样本节点向量 list (batch_size, neg_num, embed_size)\n",
    "    输出：loss - 正负样本的交叉熵 float\n",
    "    \"\"\"\n",
    "    \n",
    "    ##################################\n",
    "    # 请在这里实现SkipGram的loss计算过程\n",
    "    pos_logits = l.matmul(\n",
    "        embed_src, weight_pos, transpose_y=True)  # [batch_size, 1, 1]\n",
    "    neg_logits = l.matmul(\n",
    "        embed_src, weight_negs, transpose_y=True)  # [batch_size, 1, neg_num]\n",
    "\n",
    "    ones_label = pos_logits * 0. + 1.\n",
    "    ones_label.stop_gradient = True\n",
    "    pos_loss = l.sigmoid_cross_entropy_with_logits(pos_logits, ones_label)\n",
    "\n",
    "    zeros_label = neg_logits * 0.\n",
    "    zeros_label.stop_gradient = True\n",
    "    neg_loss = l.sigmoid_cross_entropy_with_logits(neg_logits, zeros_label)\n",
    "    \n",
    "    loss = (l.reduce_mean(pos_loss) + l.reduce_mean(neg_loss)) / 2\n",
    "    ##################################\n",
    "    return loss"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "接下来看看在ArXiv数据集上的效果吧~"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/sklearn/externals/joblib/externals/cloudpickle/cloudpickle.py:47: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses\n",
      "  import imp\n",
      "[INFO] 2020-11-25 13:13:04,391 [my_node2vec.py:  393]:\tNamespace(batch_size=512, dataset='ArXiv', epoch=5, hidden_size=128, neg_num=20, offline_learning=False, p=0.25, processes=2, q=0.25, save_path='./tmp/node2vec', use_cuda=False, use_my_model=True, use_my_sample=False, walk_len=5, win_size=5)\n",
      "2020-11-25 13:13:05,435-WARNING: paddle.fluid.layers.py_reader() may be deprecated in the near future. Please use paddle.fluid.io.DataLoader.from_generator() instead.\n",
      "[INFO] 2020-11-25 13:13:06,248 [my_node2vec.py:  358]:\tStep 1 Node2vec Loss: 0.724371  0.541657 s/step.\n",
      "[INFO] 2020-11-25 13:13:09,104 [my_node2vec.py:  358]:\tStep 10 Node2vec Loss: 0.717879  0.269546 s/step.\n",
      "[INFO] 2020-11-25 13:13:11,851 [my_node2vec.py:  358]:\tStep 20 Node2vec Loss: 0.689021  0.272080 s/step.\n",
      "[INFO] 2020-11-25 13:13:14,570 [my_node2vec.py:  358]:\tStep 30 Node2vec Loss: 0.665639  0.273426 s/step.\n",
      "[INFO] 2020-11-25 13:13:17,242 [my_node2vec.py:  358]:\tStep 40 Node2vec Loss: 0.624295  0.272290 s/step.\n",
      "[INFO] 2020-11-25 13:13:20,012 [my_node2vec.py:  358]:\tStep 50 Node2vec Loss: 0.593482  0.272751 s/step.\n",
      "[INFO] 2020-11-25 13:13:22,755 [my_node2vec.py:  358]:\tStep 60 Node2vec Loss: 0.577735  0.271013 s/step.\n",
      "[INFO] 2020-11-25 13:13:25,519 [my_node2vec.py:  358]:\tStep 70 Node2vec Loss: 0.554635  0.279671 s/step.\n",
      "[INFO] 2020-11-25 13:13:28,179 [my_node2vec.py:  358]:\tStep 80 Node2vec Loss: 0.504864  0.273981 s/step.\n",
      "[INFO] 2020-11-25 13:13:30,949 [my_node2vec.py:  358]:\tStep 90 Node2vec Loss: 0.468539  0.269737 s/step.\n",
      "[INFO] 2020-11-25 13:13:33,913 [my_node2vec.py:  358]:\tStep 100 Node2vec Loss: 0.449499  0.290091 s/step.\n",
      "[INFO] 2020-11-25 13:13:36,876 [my_node2vec.py:  358]:\tStep 110 Node2vec Loss: 0.451136  0.309641 s/step.\n",
      "[INFO] 2020-11-25 13:13:39,780 [my_node2vec.py:  358]:\tStep 120 Node2vec Loss: 0.401443  0.292098 s/step.\n",
      "[INFO] 2020-11-25 13:13:42,821 [my_node2vec.py:  358]:\tStep 130 Node2vec Loss: 0.401170  0.288948 s/step.\n",
      "[INFO] 2020-11-25 13:13:45,761 [my_node2vec.py:  358]:\tStep 140 Node2vec Loss: 0.390894  0.288139 s/step.\n",
      "[INFO] 2020-11-25 13:13:48,678 [my_node2vec.py:  358]:\tStep 150 Node2vec Loss: 0.374142  0.298069 s/step.\n",
      "[INFO] 2020-11-25 13:13:51,644 [my_node2vec.py:  358]:\tStep 160 Node2vec Loss: 0.373215  0.299066 s/step.\n",
      "[INFO] 2020-11-25 13:13:54,620 [my_node2vec.py:  358]:\tStep 170 Node2vec Loss: 0.373090  0.306728 s/step.\n",
      "[INFO] 2020-11-25 13:13:57,576 [my_node2vec.py:  358]:\tStep 180 Node2vec Loss: 0.375112  0.296412 s/step.\n",
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/sklearn/externals/joblib/externals/cloudpickle/cloudpickle.py:47: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses\n",
      "  import imp\n",
      "[INFO] 2020-11-25 13:14:01,030 [link_predict.py:  243]:\tNamespace(batch_size=None, ckpt_path='./tmp/node2vec/paddle_model', dataset='ArXiv', epoch=100, hidden_size=128, use_cuda=False)\n",
      "2020-11-25 13:14:02,114-WARNING: paddle.fluid.layers.py_reader() may be deprecated in the near future. Please use paddle.fluid.io.DataLoader.from_generator() instead.\n",
      "2020-11-25 13:14:02,139-WARNING: paddle.fluid.layers.py_reader() may be deprecated in the near future. Please use paddle.fluid.io.DataLoader.from_generator() instead.\n",
      "[INFO] 2020-11-25 13:14:03,021 [link_predict.py:  199]:\tStep 1 Train Loss: 0.793844 Train AUC: 0.529970 \n",
      "[INFO] 2020-11-25 13:14:03,224 [link_predict.py:  223]:\t\t\tStep 1 Test Loss: 1.062541 Test AUC: 0.425630 \n",
      "[INFO] 2020-11-25 13:14:06,154 [link_predict.py:  199]:\tStep 10 Train Loss: 0.834614 Train AUC: 0.467465 \n",
      "[INFO] 2020-11-25 13:14:06,302 [link_predict.py:  223]:\t\t\tStep 10 Test Loss: 0.811633 Test AUC: 0.473894 \n",
      "[INFO] 2020-11-25 13:14:09,585 [link_predict.py:  199]:\tStep 20 Train Loss: 0.738962 Train AUC: 0.503283 \n",
      "[INFO] 2020-11-25 13:14:09,730 [link_predict.py:  223]:\t\t\tStep 20 Test Loss: 0.745150 Test AUC: 0.493833 \n",
      "[INFO] 2020-11-25 13:14:12,870 [link_predict.py:  199]:\tStep 30 Train Loss: 0.700464 Train AUC: 0.550569 \n",
      "[INFO] 2020-11-25 13:14:13,018 [link_predict.py:  223]:\t\t\tStep 30 Test Loss: 0.702215 Test AUC: 0.533728 \n",
      "[INFO] 2020-11-25 13:14:16,137 [link_predict.py:  199]:\tStep 40 Train Loss: 0.686665 Train AUC: 0.603331 \n",
      "[INFO] 2020-11-25 13:14:16,279 [link_predict.py:  223]:\t\t\tStep 40 Test Loss: 0.685560 Test AUC: 0.589883 \n",
      "[INFO] 2020-11-25 13:14:19,369 [link_predict.py:  199]:\tStep 50 Train Loss: 0.678388 Train AUC: 0.652349 \n",
      "[INFO] 2020-11-25 13:14:19,513 [link_predict.py:  223]:\t\t\tStep 50 Test Loss: 0.678686 Test AUC: 0.647743 \n",
      "[INFO] 2020-11-25 13:14:22,634 [link_predict.py:  199]:\tStep 60 Train Loss: 0.673057 Train AUC: 0.684186 \n",
      "[INFO] 2020-11-25 13:14:22,777 [link_predict.py:  223]:\t\t\tStep 60 Test Loss: 0.674042 Test AUC: 0.684254 \n",
      "[INFO] 2020-11-25 13:14:25,881 [link_predict.py:  199]:\tStep 70 Train Loss: 0.670451 Train AUC: 0.704560 \n",
      "[INFO] 2020-11-25 13:14:26,023 [link_predict.py:  223]:\t\t\tStep 70 Test Loss: 0.671368 Test AUC: 0.700449 \n",
      "[INFO] 2020-11-25 13:14:29,110 [link_predict.py:  199]:\tStep 80 Train Loss: 0.668650 Train AUC: 0.728015 \n",
      "[INFO] 2020-11-25 13:14:29,251 [link_predict.py:  223]:\t\t\tStep 80 Test Loss: 0.669699 Test AUC: 0.719509 \n",
      "[INFO] 2020-11-25 13:14:32,348 [link_predict.py:  199]:\tStep 90 Train Loss: 0.667606 Train AUC: 0.736372 \n",
      "[INFO] 2020-11-25 13:14:32,491 [link_predict.py:  223]:\t\t\tStep 90 Test Loss: 0.668720 Test AUC: 0.728853 \n",
      "[INFO] 2020-11-25 13:14:35,583 [link_predict.py:  199]:\tStep 100 Train Loss: 0.667180 Train AUC: 0.740103 \n",
      "[INFO] 2020-11-25 13:14:35,724 [link_predict.py:  223]:\t\t\tStep 100 Test Loss: 0.668355 Test AUC: 0.731702 \n"
     ]
    }
   ],
   "source": [
    "!python my_node2vec.py  --use_my_model --epoch 5 # 使用自己定义的loss函数\n",
    "!python link_predict.py --ckpt_path ./tmp/node2vec/paddle_model --epoch 100"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## 3. Node2Vec采样算法\n",
    "\n",
    "\n",
    "\tNOTE：Node2Vec会根据与上个节点的距离按不同概率采样得到当前节点的下一个节点。\n",
    "\n",
    "<img src=\"https://ai-studio-static-online.cdn.bcebos.com/09001163a1064101a8dd2892eb559cf2006aa93d7fe84c70b2ad47b810f4c86a\" width=\"85%\" height=\"85%\" />\n",
    "\n",
    "PGL/pgl/graph_kernel.pyx 中用Cython语言实现了节点采样函数node2vec_sample，请试着用numpy实现自己的node2vec_sample函数吧"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing userdef_sample.py\n"
     ]
    }
   ],
   "source": [
    "%%writefile userdef_sample.py\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "def node2vec_sample(succ, prev_succ, prev_node, p, q):\n",
    "    \"\"\"\n",
    "    输入：succ - 当前节点的下一个相邻节点id列表 list (num_neighbors,)\n",
    "         prev_succ - 前一个节点的下一个相邻节点id列表 list (num_neighbors,)\n",
    "         prev_node - 前一个节点id int\n",
    "         p - 控制回到上一节点的概率 float\n",
    "         q - 控制偏向DFS还是BFS float\n",
    "    输出：下一个节点id int\n",
    "    \"\"\"\n",
    "    ##################################\n",
    "    # 请在此实现node2vec的节点采样函数\n",
    "     get_indexs = lambda xs, x:[i for (y, i) in zip(xs, range(len(xs))) if x==y]\n",
    "     succ_len = len(succ)\n",
    "     prev_succ_len = len(prev_succ)\n",
    "     prev_succ_set = set()\n",
    "     probs = []\n",
    "     prob_sum = 0\n",
    "     sampled_succ = 0\n",
    "\n",
    "     for i in range(prev_succ_len):\n",
    "        prev_succ_set.add(prev_succ[i])\n",
    "\n",
    "     for i in range(succ_len):\n",
    "        if succ[i] == prev_node:\n",
    "            prob = 1. / p\n",
    "        elif get_indexs(prev_succ_set, succ[i]) != len(prev_succ_set)-1:\n",
    "            prob = 1.\n",
    "        else:\n",
    "            prob = 1. / q\n",
    "        probs.append(prob)\n",
    "        prob_sum += prob\n",
    "\n",
    "     rand_num = random.random()*prob_sum\n",
    "      for i in range(succ_len):\n",
    "        rand_num -= probs[i]\n",
    "        if rand_num <= 0:\n",
    "            sampled_succ = succ[i]\n",
    "\n",
    "    ################################## \n",
    "\n",
    "    return sampled_succ"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/sklearn/externals/joblib/externals/cloudpickle/cloudpickle.py:47: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses\n",
      "  import imp\n",
      "[INFO] 2020-11-25 13:48:22,038 [my_node2vec.py:  393]:\tNamespace(batch_size=512, dataset='ArXiv', epoch=5, hidden_size=128, neg_num=20, offline_learning=False, p=0.25, processes=2, q=0.25, save_path='./tmp/node2vec', use_cuda=False, use_my_model=False, use_my_sample=True, walk_len=5, win_size=5)\n",
      "2020-11-25 13:48:23,071-WARNING: paddle.fluid.layers.py_reader() may be deprecated in the near future. Please use paddle.fluid.io.DataLoader.from_generator() instead.\n",
      "2020-11-25 13:48:23,101-WARNING: Your decorated reader has raised an exception!\n",
      "Exception in thread Thread-1:\n",
      "Traceback (most recent call last):\n",
      "  File \"/opt/conda/envs/python35-paddle120-env/lib/python3.7/threading.py\", line 926, in _bootstrap_inner\n",
      "    self.run()\n",
      "  File \"/opt/conda/envs/python35-paddle120-env/lib/python3.7/threading.py\", line 870, in run\n",
      "    self._target(*self._args, **self._kwargs)\n",
      "  File \"/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/fluid/layers/io.py\", line 496, in __provider_thread__\n",
      "    six.reraise(*sys.exc_info())\n",
      "  File \"/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/six.py\", line 703, in reraise\n",
      "    raise value\n",
      "  File \"/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/fluid/layers/io.py\", line 477, in __provider_thread__\n",
      "    for tensors in func():\n",
      "  File \"my_node2vec.py\", line 145, in wrapper\n",
      "    for walks in walks_generator():\n",
      "  File \"my_node2vec.py\", line 141, in walks_generator\n",
      "    walks = graph.node2vec_random_walk(nodes, walk_len, p, q)\n",
      "  File \"my_node2vec.py\", line 184, in node2vec_random_walk\n",
      "    from userdef_sample import node2vec_sample\n",
      "  File \"/home/aistudio/userdef_sample.py\", line 15\n",
      "    get_indexs = lambda xs, x:[i for (y, i) in zip(xs, range(len(xs))) if x==y]\n",
      "    ^\n",
      "IndentationError: unexpected indent\n",
      "\n",
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/fluid/executor.py:1070: UserWarning: The following exception is not an EOF exception.\n",
      "  \"The following exception is not an EOF exception.\")\n",
      "Traceback (most recent call last):\n",
      "  File \"my_node2vec.py\", line 394, in <module>\n",
      "    main(args)\n",
      "  File \"my_node2vec.py\", line 351, in main\n",
      "    return_numpy=True)[0]\n",
      "  File \"/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/fluid/executor.py\", line 1071, in run\n",
      "    six.reraise(*sys.exc_info())\n",
      "  File \"/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/six.py\", line 703, in reraise\n",
      "    raise value\n",
      "  File \"/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/fluid/executor.py\", line 1066, in run\n",
      "    return_merged=return_merged)\n",
      "  File \"/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/fluid/executor.py\", line 1154, in _run_impl\n",
      "    use_program_cache=use_program_cache)\n",
      "  File \"/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/fluid/executor.py\", line 1229, in _run_program\n",
      "    fetch_var_name)\n",
      "paddle.fluid.core_avx.EnforceNotMet: \n",
      "\n",
      "--------------------------------------------\n",
      "C++ Call Stacks (More useful to developers):\n",
      "--------------------------------------------\n",
      "0   std::string paddle::platform::GetTraceBackString<std::string const&>(std::string const&, char const*, int)\n",
      "1   paddle::platform::EnforceNotMet::EnforceNotMet(std::string const&, char const*, int)\n",
      "2   paddle::operators::reader::BlockingQueue<std::vector<paddle::framework::LoDTensor, std::allocator<paddle::framework::LoDTensor> > >::Receive(std::vector<paddle::framework::LoDTensor, std::allocator<paddle::framework::LoDTensor> >*)\n",
      "3   paddle::operators::reader::PyReader::ReadNext(std::vector<paddle::framework::LoDTensor, std::allocator<paddle::framework::LoDTensor> >*)\n",
      "4   std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<unsigned long>, std::__future_base::_Result_base::_Deleter>, unsigned long> >::_M_invoke(std::_Any_data const&)\n",
      "5   std::__future_base::_State_base::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>&, bool&)\n",
      "6   ThreadPool::ThreadPool(unsigned long)::{lambda()#1}::operator()() const\n",
      "\n",
      "------------------------------------------\n",
      "Python Call Stacks (More useful to users):\n",
      "------------------------------------------\n",
      "  File \"/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/fluid/framework.py\", line 2610, in append_op\n",
      "    attrs=kwargs.get(\"attrs\", None))\n",
      "  File \"/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/fluid/layer_helper.py\", line 43, in append_op\n",
      "    return self.main_program.current_block().append_op(*args, **kwargs)\n",
      "  File \"/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/fluid/layers/io.py\", line 894, in read_file\n",
      "    type='read', inputs={'Reader': [reader]}, outputs={'Out': out})\n",
      "  File \"my_node2vec.py\", line 54, in node2vec_model\n",
      "    src, pos, negs = l.read_file(pyreader)\n",
      "  File \"my_node2vec.py\", line 322, in main\n",
      "    dataset.graph, hidden_size=hidden_size, neg_num=neg_num)\n",
      "  File \"my_node2vec.py\", line 394, in <module>\n",
      "    main(args)\n",
      "\n",
      "----------------------\n",
      "Error Message Summary:\n",
      "----------------------\n",
      "Error: Blocking queue is killed because the data reader raises an exception\n",
      "  [Hint: Expected killed_ != true, but received killed_:1 == true:1.] at (/paddle/paddle/fluid/operators/reader/blocking_queue.h:141)\n",
      "  [operator < read > error]\n",
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/sklearn/externals/joblib/externals/cloudpickle/cloudpickle.py:47: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses\n",
      "  import imp\n",
      "[INFO] 2020-11-25 13:48:25,115 [link_predict.py:  243]:\tNamespace(batch_size=None, ckpt_path='./tmp/node2vec/paddle_model', dataset='ArXiv', epoch=100, hidden_size=128, use_cuda=False)\n",
      "2020-11-25 13:48:26,121-WARNING: paddle.fluid.layers.py_reader() may be deprecated in the near future. Please use paddle.fluid.io.DataLoader.from_generator() instead.\n",
      "2020-11-25 13:48:26,146-WARNING: paddle.fluid.layers.py_reader() may be deprecated in the near future. Please use paddle.fluid.io.DataLoader.from_generator() instead.\n",
      "[INFO] 2020-11-25 13:48:26,974 [link_predict.py:  199]:\tStep 1 Train Loss: 1.069654 Train AUC: 0.428611 \n",
      "[INFO] 2020-11-25 13:48:27,179 [link_predict.py:  223]:\t\t\tStep 1 Test Loss: 0.812436 Test AUC: 0.524208 \n",
      "[INFO] 2020-11-25 13:48:29,971 [link_predict.py:  199]:\tStep 10 Train Loss: 0.789343 Train AUC: 0.494141 \n",
      "[INFO] 2020-11-25 13:48:30,112 [link_predict.py:  223]:\t\t\tStep 10 Test Loss: 0.771981 Test AUC: 0.519920 \n",
      "[INFO] 2020-11-25 13:48:33,276 [link_predict.py:  199]:\tStep 20 Train Loss: 0.752957 Train AUC: 0.495103 \n",
      "[INFO] 2020-11-25 13:48:33,417 [link_predict.py:  223]:\t\t\tStep 20 Test Loss: 0.737894 Test AUC: 0.507627 \n",
      "[INFO] 2020-11-25 13:48:36,509 [link_predict.py:  199]:\tStep 30 Train Loss: 0.712912 Train AUC: 0.517710 \n",
      "[INFO] 2020-11-25 13:48:36,650 [link_predict.py:  223]:\t\t\tStep 30 Test Loss: 0.710665 Test AUC: 0.517714 \n",
      "[INFO] 2020-11-25 13:48:39,777 [link_predict.py:  199]:\tStep 40 Train Loss: 0.688980 Train AUC: 0.565230 \n",
      "[INFO] 2020-11-25 13:48:39,920 [link_predict.py:  223]:\t\t\tStep 40 Test Loss: 0.689768 Test AUC: 0.556606 \n",
      "[INFO] 2020-11-25 13:48:43,034 [link_predict.py:  199]:\tStep 50 Train Loss: 0.679110 Train AUC: 0.629778 \n",
      "[INFO] 2020-11-25 13:48:43,177 [link_predict.py:  223]:\t\t\tStep 50 Test Loss: 0.679430 Test AUC: 0.619837 \n",
      "[INFO] 2020-11-25 13:48:46,282 [link_predict.py:  199]:\tStep 60 Train Loss: 0.674461 Train AUC: 0.683332 \n",
      "[INFO] 2020-11-25 13:48:46,425 [link_predict.py:  223]:\t\t\tStep 60 Test Loss: 0.675057 Test AUC: 0.677746 \n",
      "[INFO] 2020-11-25 13:48:49,603 [link_predict.py:  199]:\tStep 70 Train Loss: 0.671366 Train AUC: 0.706961 \n",
      "[INFO] 2020-11-25 13:48:49,749 [link_predict.py:  223]:\t\t\tStep 70 Test Loss: 0.672285 Test AUC: 0.703720 \n",
      "[INFO] 2020-11-25 13:48:52,974 [link_predict.py:  199]:\tStep 80 Train Loss: 0.669598 Train AUC: 0.720434 \n",
      "[INFO] 2020-11-25 13:48:53,117 [link_predict.py:  223]:\t\t\tStep 80 Test Loss: 0.670587 Test AUC: 0.713625 \n",
      "[INFO] 2020-11-25 13:48:56,264 [link_predict.py:  199]:\tStep 90 Train Loss: 0.668504 Train AUC: 0.734102 \n",
      "[INFO] 2020-11-25 13:48:56,410 [link_predict.py:  223]:\t\t\tStep 90 Test Loss: 0.669569 Test AUC: 0.726433 \n",
      "[INFO] 2020-11-25 13:48:59,569 [link_predict.py:  199]:\tStep 100 Train Loss: 0.668056 Train AUC: 0.735551 \n",
      "[INFO] 2020-11-25 13:48:59,713 [link_predict.py:  223]:\t\t\tStep 100 Test Loss: 0.669189 Test AUC: 0.727469 \n"
     ]
    }
   ],
   "source": [
    "!python my_node2vec.py  --use_my_sample --epoch 5 # 用自己实现的采样函数训练模型\n",
    "!python link_predict.py --ckpt_path ./tmp/node2vec/paddle_model --epoch 100 # 测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "PaddlePaddle 1.8.4 (Python 3.5)",
   "language": "python",
   "name": "py35-paddle1.2.0"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
